"""
The MIT License (MIT)
Copyright © 2020 Walkline Wang (https://walkline.wang)
https://gitee.com/walkline/micropython-led-clock
"""
from machine import SPI
import utime as time
from micropython import const


# font = (  #8x8矩阵中的字符集5x8
#   0x0e, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0e, 0x00,   # 0x30, 0
#   0x04, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x0e, 0x00,   # 0x31, 1
#   0x0e, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1f, 0x00,   # 0x32, 2
#   0x0e, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0e, 0x00,   # 0x33, 3
#   0x02, 0x06, 0x0a, 0x12, 0x1f, 0x02, 0x02, 0x00,   # 0x34, 4
#   0x1f, 0x10, 0x1e, 0x01, 0x01, 0x11, 0x0e, 0x00,   # 0x35, 5
#   0x06, 0x08, 0x10, 0x1e, 0x11, 0x11, 0x0e, 0x00,   # 0x36, 6
#   0x1f, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08, 0x00,   # 0x37, 7
#   0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, 0x00,   # 0x38, 8
#   0x0e, 0x11, 0x11, 0x0f, 0x01, 0x02, 0x0c, 0x00,   # 0x39, 9  
# )

font_5X6_2 = {
	'width': 5,
	'height': 6,
	'0': [0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00],
	'1': [0x04, 0x0c, 0x04, 0x04, 0x0e, 0x00],
	'2': '0x0c, 0x12, 0x04, 0x08, 0x1e, 0x00',
	'3': '0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x00',
	'4': '0x14, 0x14, 0x0e, 0x04, 0x04, 0x00',
	'5': '0x1e, 0x10, 0x1c, 0x02, 0x1c, 0x00',
	'6': '0x0c, 0x10, 0x1c, 0x12, 0x0c, 0x00',
	'7': '0x1e, 0x02, 0x04, 0x08, 0x08, 0x00',
	'8': '0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x00',
	'9': '0x0c, 0x12, 0x0e, 0x02, 0x0c, 0x00',
	'a': '0x0c, 0x12, 0x1e, 0x12, 0x12, 0x00',
	'b': '0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00',
	'c': '0x0c, 0x12, 0x10, 0x12, 0x0c, 0x00',
	'd': '0x1c, 0x12, 0x12, 0x12, 0x1c, 0x00',
	'e': '0x0e, 0x10, 0x1e, 0x10, 0x0e, 0x00',
	'f': '0x0e, 0x10, 0x1e, 0x10, 0x10, 0x00',
	'g': '0x0e, 0x10, 0x16, 0x12, 0x0e, 0x00',
	'h': '0x12, 0x12, 0x1e, 0x12, 0x12, 0x00',
	'i': '0x0e, 0x04, 0x04, 0x04, 0x0e, 0x00',
	'j': '0x1e, 0x04, 0x04, 0x14, 0x08, 0x00',
	'k': '0x12, 0x14, 0x18, 0x14, 0x12, 0x00',
	'l': '0x08, 0x08, 0x08, 0x08, 0x0e, 0x00',
	'm': '0x11, 0x1b, 0x15, 0x11, 0x11, 0x00',
	'n': '0x12, 0x1a, 0x16, 0x12, 0x12, 0x00',
	'o': '0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00',
	'p': '0x1c, 0x12, 0x1c, 0x10, 0x10, 0x00',
	'q': '0x0c, 0x12, 0x12, 0x12, 0x0c, 0x04',
	'r': '0x1c, 0x12, 0x1c, 0x14, 0x12, 0x00',
	's': '0x06, 0x08, 0x04, 0x02, 0x0c, 0x00',
	't': '0x0e, 0x04, 0x04, 0x04, 0x04, 0x00',
	'u': '0x12, 0x12, 0x12, 0x12, 0x0c, 0x00',
	'v': '0x11, 0x11, 0x11, 0x0a, 0x04, 0x00',
	'w': '0x11, 0x11, 0x15, 0x1b, 0x11, 0x00',
	'x': '0x12, 0x12, 0x0c, 0x12, 0x12, 0x00',
	'y': '0x11, 0x0a, 0x04, 0x04, 0x04, 0x00',
	'z': '0x0e, 0x02, 0x04, 0x08, 0x0e, 0x00',
	'A': '0x0c, 0x12, 0x1e, 0x12, 0x12, 0x00',
	'B': '0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00',
	'C': '0x0c, 0x12, 0x10, 0x12, 0x0c, 0x00',
	'D': '0x1c, 0x12, 0x12, 0x12, 0x1c, 0x00',
	'E': '0x0e, 0x10, 0x1e, 0x10, 0x0e, 0x00',
	'F': '0x0e, 0x10, 0x1e, 0x10, 0x10, 0x00',
	'G': '0x0e, 0x10, 0x16, 0x12, 0x0e, 0x00',
	'H': '0x12, 0x12, 0x1e, 0x12, 0x12, 0x00',
	'I': '0x0e, 0x04, 0x04, 0x04, 0x0e, 0x00',
	'J': '0x1e, 0x04, 0x04, 0x14, 0x08, 0x00',
	'K': '0x12, 0x14, 0x18, 0x14, 0x12, 0x00',
	'L': '0x08, 0x08, 0x08, 0x08, 0x0e, 0x00',
	'M': '0x11, 0x1b, 0x15, 0x11, 0x11, 0x00',
	'N': '0x12, 0x1a, 0x16, 0x12, 0x12, 0x00',
	'O': '0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00',
	'P': '0x1c, 0x12, 0x1c, 0x10, 0x10, 0x00',
	'Q': '0x0c, 0x12, 0x12, 0x12, 0x0c, 0x04',
	'R': '0x1c, 0x12, 0x1c, 0x14, 0x12, 0x00',
	'S': '0x06, 0x08, 0x04, 0x02, 0x0c, 0x00',
	'T': '0x0e, 0x04, 0x04, 0x04, 0x04, 0x00',
	'U': '0x12, 0x12, 0x12, 0x12, 0x0c, 0x00',
	'V': '0x11, 0x11, 0x11, 0x0a, 0x04, 0x00',
	'W': '0x11, 0x11, 0x15, 0x1b, 0x11, 0x00',
	'X': '0x12, 0x12, 0x0c, 0x12, 0x12, 0x00',
	'Y': '0x11, 0x0a, 0x04, 0x04, 0x04, 0x00',
	'Z': '0x0e, 0x02, 0x04, 0x08, 0x0e, 0x00'
}

_NOOP = const(0)
_DIGIT0 = const(1)
_DECODEMODE = const(9)
_INTENSITY = const(10)
_SCANLIMIT = const(11)
_SHUTDOWN = const(12)
_DISPLAYTEST = const(15)


class Matrix8x8Exception(BaseException):
	pass


class Matrix8x8:
	def __init__(self, spi, cs, num=1):
		assert num >= 1, Matrix8x8Exception("num must be >= 0")

		self.__spi = spi
		self.__num = num
		self.__cs = cs
		self.__cs.init(mode=cs.OUT, value=1)
		self.__buffer = bytearray(8 * self.__num)
		self.__init()

	def __write(self, command, data):
		self.__cs(0)
		for count in range(self.__num):
			self.__spi.write(bytearray([command, data]))
		self.__cs(1)

	def __init(self):
		for command, data in (
			(_SHUTDOWN, 0),
			(_DISPLAYTEST, 0),
			(_SCANLIMIT, 7),
			(_DECODEMODE, 0),
			(_INTENSITY, 7),
			(_SHUTDOWN, 1),
		):
			self.__write(command, data)

	def brightness(self, value):
		assert 0 <= value <=15, Matrix8x8Exception("Brightness out of range")

		self.__write(_INTENSITY, value)

	# def set_number(self,number,psion): # 数字，位置
	# 	for j in range(8):
	# 		self.__buffer[j*self.__num+psion] = font[number*8+j]

	def text(self, string, x, y, color=0):
		index = 0
		width = font_5X6_2['width']

		for letter in string:
			for count in range(width):
				self.__buffer[count * self.__num + y] = font_5X6_2[letter][count] << (8 - width - x)

			index += 1


	# def up_roll(self,nub,psion): # 数字，位置
	# 	for i in range(8):
	# 		for j in range(7):
	# 			self.buff[4*j+psion] =self.buff[4*(j+1)+psion]
	# 		self.buff[4*7+psion] = font[nub*8+i]
	# 		self.show()
	# 		time.sleep_ms(80)
	# 		display.buff = [0]*8*4
	# 		display.show()

	# def down_roll(self,nub,psion): # 数字，位置
	# 	for i in range(7,-1,-1):
	# 		for j in range(7,0,-1):
	# 			self.buff[4*j+psion] =self.buff[4*(j-1)+psion]
	# 		self.buff[0+psion] = font[nub*8+i]
	# 		self.show()
	# 		time.sleep_ms(80)
	# 		display.buff = [0]*8*4
	# 		display.show()

	def fill(self, color=0):
		self.__buffer = bytearray([0 if color == 0 else 0xff] * 8 * self.__num)

	def show(self):
		for y in range(8):
			self.__cs(0)
			for count in range(self.__num):
				self.__spi.write(bytearray([_DIGIT0 + y, self.__buffer[(y * self.__num) + count]]))
			self.__cs(1)

	def print_buffer(self):
		print(self.__buffer)



from machine import Pin


def run_test():
	spi = SPI(1, baudrate=10000000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13))
	display = Matrix8x8(spi, Pin(27), 1)

	display.fill(0)
	# display.set_number(3, 0)
	display.text("E", 0, 1, 1)
	display.print_buffer()
	display.show()

	# while True:
	# 	for i in range(10):
	# 		display.up_roll(i,0)
	# 		display.down_roll(9-i,1)
	# 		display.up_roll(i,2)
	# 		display.down_roll(9-i,3)

	# 	for i in range(10):
	# 		display.up_roll(i,1)
	# 		display.up_roll(i,3)

		#display.down_4_roll((0,0,0,0),(9,9,9,9))
		# for i in range(9999,9980,-1):
		# 	display.down_4_roll(digt(i),digt(i-1))
		# 	time.sleep_ms(300)

		# for i in range(9980,9999):
		# 	display.up_4_roll(digt(i),digt(i+1))
		# 	time.sleep_ms(300)


if __name__ == "__main__":
	try:
		run_test()
	except KeyboardInterrupt:
		print("\nPRESS CTRL+D TO RESET DEVICE")
